/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.alien.admin.modules.container.service.impl;

import cn.hutool.core.bean.BeanUtil;

import com.alien.admin.modules.container.domain.K8sPodMetricStatus;
import com.alien.admin.modules.container.domain.K8sPodMetricStatusHistory;
import com.alien.admin.modules.container.repository.K8sPodMetricStatusHistoryRepository;
import com.alien.admin.modules.container.service.dto.K8sProjectQueryCriteria;
import com.alien.admin.modules.deploy.domain.DpServerConfig;

import com.alien.admin.modules.deploy.service.DpServerConfigService;
import com.alien.admin.utils.ValidationUtil;
import com.alien.admin.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.alien.admin.modules.container.repository.K8sPodMetricStatusRepository;
import com.alien.admin.modules.container.service.K8sPodMetricStatusService;
import com.alien.admin.modules.container.service.dto.K8sPodMetricStatusDto;
import com.alien.admin.modules.container.service.dto.K8sPodMetricStatusQueryCriteria;
import com.alien.admin.modules.container.service.mapstruct.K8sPodMetricStatusMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.alien.admin.utils.PageUtil;
import com.alien.admin.utils.QueryHelp;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.stream.Collectors;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author zhouseyi
* @date 2021-10-20
**/
@Service
@RequiredArgsConstructor
public class K8sPodMetricStatusServiceImpl implements K8sPodMetricStatusService {

    private final K8sPodMetricStatusRepository k8sPodMetricStatusRepository;
    private final K8sPodMetricStatusMapper k8sPodMetricStatusMapper;
    private final K8sPodMetricStatusHistoryRepository k8sPodMetricStatusHistoryRepository;
    private final DpServerConfigService dpServerConfigService;

    @Override
    public Map<String,Object> queryAll(K8sPodMetricStatusQueryCriteria criteria, Pageable pageable){
        Page<K8sPodMetricStatus> page = k8sPodMetricStatusRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(k8sPodMetricStatusMapper::toDto));
    }

    @Override
    public List<K8sPodMetricStatusDto> queryAll(K8sPodMetricStatusQueryCriteria criteria){
        return k8sPodMetricStatusMapper.toDto(k8sPodMetricStatusRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public K8sPodMetricStatusDto findById(String podName) {
        K8sPodMetricStatus k8sPodMetricStatus = k8sPodMetricStatusRepository.findById(podName).orElseGet(K8sPodMetricStatus::new);
        ValidationUtil.isNull(k8sPodMetricStatus.getPodName(),"K8sPodMetricStatus","podName",podName);
        return k8sPodMetricStatusMapper.toDto(k8sPodMetricStatus);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public K8sPodMetricStatusDto create(K8sPodMetricStatus resources) {
        resources.setPodName(IdUtil.simpleUUID());
        return k8sPodMetricStatusMapper.toDto(k8sPodMetricStatusRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(K8sPodMetricStatus resources) {
        K8sPodMetricStatus k8sPodMetricStatus = k8sPodMetricStatusRepository.findById(resources.getPodName()).orElseGet(K8sPodMetricStatus::new);
        ValidationUtil.isNull( k8sPodMetricStatus.getPodName(),"K8sPodMetricStatus","id",resources.getPodName());
        k8sPodMetricStatus.copy(resources);
        k8sPodMetricStatusRepository.save(k8sPodMetricStatus);
    }

    @Override
    public void deleteAll(String[] ids) {
        for (String podName : ids) {
            k8sPodMetricStatusRepository.deleteById(podName);
        }
    }

    @Override
    public void download(List<K8sPodMetricStatusDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (K8sPodMetricStatusDto k8sPodMetricStatus : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put(" deploymentName",  k8sPodMetricStatus.getDeploymentName());
            map.put(" cpu",  k8sPodMetricStatus.getCpu());
            map.put(" mem",  k8sPodMetricStatus.getMem());
            map.put(" minute",  k8sPodMetricStatus.getMininute());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void discardK8sPodMetricStatus(Integer k8sId, String namespace) {
        K8sPodMetricStatusQueryCriteria criteria = new K8sPodMetricStatusQueryCriteria();
        criteria.setK8sId(k8sId);
        criteria.setNamespace(namespace);
        List<K8sPodMetricStatus> k8sPodMetricStatusList = k8sPodMetricStatusRepository.findAll((root, criteriaQuery, criteriaBuilder)
                -> QueryHelp.getPredicate(root,criteria,criteriaBuilder));

        // 清空
        k8sPodMetricStatusRepository.deleteAllByK8sIdAndNamespace(k8sId, namespace);

        // k8sPodMetricStatusList 迁移到history表
        List<K8sPodMetricStatusHistory> k8sPodMetricStatusHistoryList = k8sPodMetricStatusList.stream().map(k8sPodMetricStatus -> {
            K8sPodMetricStatusHistory k8sPodMetricStatusHistory = new K8sPodMetricStatusHistory();
            BeanUtil.copyProperties(k8sPodMetricStatus, k8sPodMetricStatusHistory);
            return k8sPodMetricStatusHistory;
        }).collect(Collectors.toList());
        k8sPodMetricStatusHistoryRepository.saveAll(k8sPodMetricStatusHistoryList);
        System.out.println(k8sPodMetricStatusList.size());
    }

    @Override
    public void batchSave(List<K8sPodMetricStatus> k8sPodMetricStatusList) {
        k8sPodMetricStatusRepository.saveAll(k8sPodMetricStatusList);
    }

    @Override
    public List<K8sPodMetricStatus> queryDeploymentMetrics() {
        List<Map<String, Object>> k8sPodMetricStatusMapList = k8sPodMetricStatusRepository.queryDeploymentMetrics();

        List<K8sPodMetricStatus> k8sPodMetricStatusList = k8sPodMetricStatusMapList.stream().map(itemMap -> {
            Integer k8sId = (Integer)itemMap.get("k8s_id");
            String namespace = (String)itemMap.get("namespace");
            String deploymentName = (String)itemMap.get("deployment_name");
            BigDecimal mem = (BigDecimal)itemMap.get("mem");
            Double cpu = (Double)itemMap.get("cpu");

            K8sPodMetricStatus k8sPodMetricStatus = new K8sPodMetricStatus();
            k8sPodMetricStatus.setK8sId(k8sId);
            k8sPodMetricStatus.setNamespace(namespace);
            k8sPodMetricStatus.setDeploymentName(deploymentName);
            k8sPodMetricStatus.setMem(mem.longValue());
            k8sPodMetricStatus.setCpu(cpu);

            return k8sPodMetricStatus;
        }).collect(Collectors.toList());
        return k8sPodMetricStatusList;
    }

    @Override
    public K8sPodMetricStatus queryPodMetric(K8sProjectQueryCriteria criteria) {
        DpServerConfig dpServerConfig = dpServerConfigService.findDpServerConfig(criteria);

        K8sPodMetricStatus k8sPodMetricStatus = k8sPodMetricStatusRepository.queryFirstByK8sIdAndNamespaceAndPodName(dpServerConfig.getK8sInstanceId(),
                dpServerConfig.getK8sNameSpace(), criteria.getPodName());
        return k8sPodMetricStatus;
    }
}
